//
//  ReportManager.m
//  Pennyworth Punch Clock
//
//  Created by Chris Karr on 7/24/08.
//  Copyright 2008 Northwestern University. All rights reserved.
//

#import "ReportManager.h"

#define GENERATED_FILE [NSString stringWithFormat:@"%@/ppc-generated.html", TMP_DIR]
#define REPORT_FILE [NSString stringWithFormat:@"%@/ppc-report.xml", TMP_DIR]
#define CSS_FILE [NSString stringWithFormat:@"%@/ppc.css", TMP_DIR]

@implementation ReportManager

- (NSArray *) getReports
{
	NSArray * xsls = [[NSBundle mainBundle] pathsForResourcesOfType:@"xsl" inDirectory:nil];
	
	NSMutableArray * reports = [NSMutableArray array];
	
	for (NSString * xsl in xsls)
	{
		NSMutableDictionary * xslDict = [NSMutableDictionary dictionary];
		
		[xslDict setValue:[[xsl lastPathComponent] stringByDeletingPathExtension] forKey:@"name"];
		[xslDict setValue:xsl forKey:@"path"];
		[xslDict setValue:[xsl pathExtension] forKey:@"kind"];
		
		[reports addObject:xslDict];
	}
	
	return reports;
}

- (IBAction) generateReport:(id) sender
{
	[[NSFileManager defaultManager] createDirectoryAtPath:[GENERATED_FILE stringByDeletingLastPathComponent] attributes:nil];
	[[NSFileManager defaultManager] copyPath:[[NSBundle mainBundle] pathForResource:@"ppc" ofType:@"css"] toPath:CSS_FILE handler:nil];
	
	NSMutableDictionary * statistics = [NSMutableDictionary dictionary];
	
	NSPredicate * sliceFilter = [[NSApp delegate] getSliceFilter];

	NSXMLDocument * xml = [[NSXMLDocument alloc] initWithXMLString:@"<report />" options:0 error:NULL];
	
	NSXMLElement * root = [xml rootElement];
	[root addAttribute:[NSXMLNode attributeWithName:@"generated" stringValue:[[NSDate date] description]]];
	
	NSXMLElement * log = [NSXMLElement elementWithName:@"log"];
	[root addChild:log];
	
	NSMutableDictionary * streamsStatistics = [NSMutableDictionary dictionary];
	
	for (NSManagedObject * stream in [streamsController arrangedObjects])
	{
		NSXMLElement * streamElement = [NSXMLNode elementWithName:@"stream"];
		[streamElement addAttribute:[NSXMLNode attributeWithName:@"name" stringValue:[stream valueForKey:@"name"]]];
		
		NSData * colorData = [stream valueForKey:@"color"];
		
		if (colorData != nil)
		{
			NSColor * color = [NSUnarchiver unarchiveObjectWithData:colorData];
			[streamElement addAttribute:[NSXMLNode attributeWithName:@"color" stringValue:[color description]]];
		}
		
		NSSet * slices = [stream mutableSetValueForKey:@"slices"];
		
		NSMutableArray * matches = [NSMutableArray array];
		
		for (NSManagedObject * slice in slices)
		{
			if (sliceFilter == nil)
				[matches addObject:slice];
			else if ([sliceFilter evaluateWithObject:slice])
				[matches addObject:slice];
		}
		
		NSSortDescriptor * sort = [[NSSortDescriptor alloc] initWithKey:@"startDate" ascending:YES];
		
		NSMutableDictionary * streamStatistics = [NSMutableDictionary dictionary];
		
		for (NSManagedObject * slice in [matches sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]])
		{
			NSInteger count = 0;
			CGFloat duration = 0;
			
			NSString * sliceName = [slice valueForKey:@"name"];
			NSDate * sliceStart = [slice valueForKey:@"startDate"];
			NSDate * sliceEnd = [slice valueForKey:@"endDate"];
			
			NSMutableDictionary * sliceStatistics = [streamStatistics valueForKey:sliceName];
			
			if (sliceStatistics == nil)
			{
				sliceStatistics = [NSMutableDictionary dictionary];
				[sliceStatistics setValue:sliceName forKey:@"name"];
				[streamStatistics setValue:sliceStatistics forKey:sliceName];
			}
			else
			{
				count = [[sliceStatistics valueForKey:@"count"] integerValue];
				duration = [[sliceStatistics valueForKey:@"duration"] floatValue];
			}
			
			NSXMLElement * sliceElement = [NSXMLNode elementWithName:@"slice"];
			
			[sliceElement addAttribute:[NSXMLNode attributeWithName:@"name" stringValue:sliceName]];
			[sliceElement addAttribute:[NSXMLNode attributeWithName:@"startDate" stringValue:[sliceStart description]]];
			
			if (sliceEnd != nil)
				[sliceElement addAttribute:[NSXMLNode attributeWithName:@"endDate" stringValue:[sliceEnd description]]];
			else
				sliceEnd = [NSDate date];
			
			/* statistics */
			
			[sliceStatistics setValue:[NSNumber numberWithInteger:(count + 1)] forKey:@"count"];
			[sliceStatistics setValue:[NSNumber numberWithFloat:(duration + [sliceEnd timeIntervalSinceDate:sliceStart])] forKey:@"duration"];
			
			[streamElement addChild:sliceElement];
		}
		
		[statistics setObject:streamStatistics forKey:[stream valueForKey:@"name"]];
		
		[streamsStatistics setValue:streamStatistics forKey:[stream valueForKey:@"name"]];
		
		[log addChild:streamElement];
	}
	
	NSXMLElement * statsElement = [NSXMLElement elementWithName:@"statistics"];
	
	NSSortDescriptor * duration = [[NSSortDescriptor alloc] initWithKey:@"duration" ascending:NO];
	
	for (NSString * stream in [[streamsStatistics allKeys] sortedArrayUsingSelector:@selector(compare:)])
	{
		NSXMLElement * streamElement = [NSXMLElement elementWithName:@"stream"];
		[streamElement addAttribute:[NSXMLNode attributeWithName:@"name" stringValue:stream]];
		
		NSDictionary * streamDict = [streamsStatistics valueForKey:stream];
		
		for (NSDictionary * sliceDict in [[streamDict allValues] sortedArrayUsingDescriptors:[NSArray arrayWithObject:duration]])
		{
			NSXMLElement * sliceElement = [NSXMLElement elementWithName:@"slice"];
			
			[sliceElement addAttribute:[NSXMLNode attributeWithName:@"name" stringValue:[sliceDict valueForKey:@"name"]]];
			[sliceElement addAttribute:[NSXMLNode attributeWithName:@"duration" stringValue:[NSString stringWithFormat:@"%.2f", [[sliceDict valueForKey:@"duration"] floatValue]]]];
			[sliceElement addAttribute:[NSXMLNode attributeWithName:@"count" stringValue:[NSString stringWithFormat:@"%d", [[sliceDict valueForKey:@"count"] integerValue]]]];
			
			[streamElement addChild:sliceElement];
		}
		
		[statsElement addChild:streamElement];
	}
	
	[root addChild:statsElement];
	
	[[xml XMLData] writeToFile:REPORT_FILE atomically:YES];
	[xml release];
	
	NSDictionary * selection = [[reportsController selectedObjects] lastObject];
	
	if ([[selection valueForKey:@"kind"] isEqual:@"xsl"])
	{
		NSTask * xslTask = [NSTask launchedTaskWithLaunchPath:@"/usr/bin/xsltproc" 
													arguments:[NSArray arrayWithObjects:@"--novalid", @"-o", GENERATED_FILE,
															   [selection valueForKey:@"path"], REPORT_FILE, nil]];
		
		[xslTask waitUntilExit];
	}
	
	[[reportView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:GENERATED_FILE]]];
	
	[reportWindow setTitle:[selection valueForKey:@"name"]];
	[reportWindow makeKeyAndOrderFront:sender];
}


@end
